#include "game.h"
#include <iostream>
namespace Tetris{

Game::Game() : p_table(NULL),p_state(NULL),currentShape(NULL),nextShape(NULL) {
	this->initial();
}

void Game::Resume(){
	this->destroy();
	this->initial();
	this->pause = false;
}

void Game::initial(){
	this->score = 0;
	this->pause = true;
	this->player = "HJ";
	this->gameOver = false;
	this->generateState();
}

bool Game::GameOver() const{
	return this->gameOver;
}

void Game::destroy(){
	if(this->currentShape){
		delete this->currentShape;
		this->currentShape = NULL;
	}
	if(this->nextShape){
		delete this->nextShape;
		this->nextShape = NULL;
	}
	if(this->p_table) {
		delete this->p_table;
		this->p_table = NULL;
	}
	if(this->p_state) {
		delete this->p_state;
		this->p_state = NULL;
	}
}

Game::~Game(){
	this->destroy();
}
void Game::SetPlayer(std::string player){
	this->player = player;
}


std::string Game::GetPlayer() const{
	return this->player;
}
int Game::GetScore() const{
	return this->score;
}

const Shape* Game::NextShape() const{
	return this->nextShape;
}
void Game::MoveLeft(){
	if(this->IsPause() || this->GameOver()) return;
	if(this->p_state)
		this->p_state->MoveLeft();
}
void Game::MoveRight(){
	if(this->IsPause() || this->GameOver()) return;
	if(this->p_state)
		this->p_state->MoveRight();	
}
void Game::MoveDown(){
	if(this->IsPause() || this->GameOver()) return;
	if(this->p_state && !this->p_state->MoveDown()){
		int n = this->p_state->UpdateTable();
		if(n < 0){
			this->gameOver = true;
			return;
		}
		this->score += n * n;
		this->generateState();
	}
}
void Game::MoveBottom(){
	if(this->IsPause() || this->GameOver()) return;
	if(this->p_state){
		this->p_state->MoveBottom();
		this->MoveDown();
	}
}
void Game::Transform(){
	if(this->IsPause() || this->GameOver()) return;
	if(this->p_state)
		this->p_state->Transform();
}
void Game::TogglePause(){
	this->pause = !this->pause;
}
bool Game::IsPause() const{
	return this->pause;
}

const Table_State* Game::GetCurrentState() const{
	return this->p_state;
}

void Game::generateState(){
	if(this->currentShape)
		delete this->currentShape;
	if(!this->nextShape)
		this->nextShape = this->randomCreateShape();
	this->currentShape = this->nextShape;
	this->nextShape = this->randomCreateShape();
	if(!this->p_table)
		this->p_table = new Table();
	if(this->p_state)
		delete this->p_state;
	this->p_state = new Table_State(this->p_table,this->currentShape);
	if(!this->p_state->CanGenerateShape())
		this->gameOver = true;
}

Shape* Game::randomCreateShape(){
	Shape* p = NULL;
	switch(MyRand::Instance()->Next() % 7){
	case 0:
		p = new Shape1(); break;
	case 1:
		p = new Shape2(); break;
	case 2:
		p = new Shape3(); break;
	case 3:
		p = new Shape4(); break;
	case 4:
		p = new Shape5(); break;
	case 5:
		p = new Shape6(); break;
	case 6:
		p = new Shape7(); break;
	default:
		p = new Shape1(); break;
	}
	return p;
}

}